import cv2
import math
import numpy as np

img1=cv2.imread(r'C:\Users\ASUS\Desktop\5.jpg') #读取图片
img=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)#读灰度图
'''
_,threld=cv2.threshold(img,0,0xff,cv2.THRESH_OTSU) #全局大津算法划分区域,对图片下部分米粒分割效果不是很好
element=cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3)) #形态学去噪
threld=cv2.morphologyEx(threld,cv2.MORPH_OPEN,element) #开运算
'''

threld=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,101,1)#使用局部大津算法划分区域效果更好一些
element=cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3)) #形态学去噪
dst=cv2.morphologyEx(threld,cv2.MORPH_OPEN,element) #开运算

bin,cnt,h=cv2.findContours(dst,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)#轮廓检测
cv2.drawContours(dst,cnt,-1,(120,0,0),2)#绘制轮廓

count=0#米粒总数
averange=0#米粒面积平均
lengh=0#米粒长度均值
L=[]#长度值集合
#遍历米粒
for n in range(len(cnt),0,-1):
    c=cnt[n-1]
    area=cv2.contourArea(c)
    if area<100:
        continue

    count+=1
    averange+=area
    print("{}-blob:{}".format(count,area))#打印面积数量
    x,y,w,h=cv2.boundingRect(c)
    cv2.rectangle(img1,(x,y),(x+w,y+h),(0,0,0xff),1)#画最小矩形
    lengh+=math.sqrt(w**2+h**2)
    L.append(lengh)
    cv2.putText(img1,str(count),(x,y),cv2.FONT_HERSHEY_COMPLEX,0.4,(0,0xff,0))#在米粒左上角编号

var=np.var(L)#计算方差
var=round(var,2)
sigma=round(math.sqrt(var),2)#计算sigma
count2=0#范围内的米粒数量
u=lengh/count
for nums in L:
    if (u-3*sigma)<nums<(u+3*sigma):
        count2+=1



print("米粒面积：",round(averange/count,2))
print("米粒长度：",round(lengh/count,2))
print("米粒方差：",var)
print("在范围内的米粒数：",count2)
cv2.imshow('1',img1)


cv2.waitKey()
cv2.destroyAllWindows()

'''
比较成功的标记出来米粒，但是对于一些靠近的米粒以及一些噪声检测不准确，导致方差较大，影响后续检测结果。
'''